﻿/*
 * Mutex.h
 */

#ifndef __GDK_MUTEX_H__
#define __GDK_MUTEX_H__

#include <gdk/core/Types.h>
#include <gdk/core/Unknown.h>

#if !defined(_WIN32)
#include <pthread.h>
#endif


namespace gdk
{


#ifdef _WIN32

class Mutex
{
private:
	CRITICAL_SECTION	_cs;

public:
	__INLINE__ Mutex(void)
	{
		::InitializeCriticalSection(&_cs);
	}
	__INLINE__ ~Mutex(void)
	{
		::DeleteCriticalSection(&_cs);
	}

private:
	Mutex& operator =(const Mutex &)
	{
		GDK_ASSERT(false);

		return *this;
	}

public:
	__INLINE__ void lock(void)
	{
		::EnterCriticalSection(&_cs);
	}
	__INLINE__ void unlock(void)
	{
		::LeaveCriticalSection(&_cs);
	}
};

#else

class Mutex
{
private:
	pthread_mutex_t		_mutex;

public:
	GDK_CORE_EXPORT Mutex(void);
	__INLINE__ ~Mutex(void)
	{
		pthread_mutex_destroy(&_mutex);
	}

private:
	Mutex& operator =(const Mutex &)
	{
		GDK_ASSERT(false);

		return *this;
	}

public:
	__INLINE__ void lock(void)
	{
		pthread_mutex_lock(&_mutex);
	}
	__INLINE__ void unlock(void)
	{
		pthread_mutex_unlock(&_mutex);
	}
};



#endif



class MutexLock
{
private:
	Mutex&	_mutex;

private:
	MutexLock& operator =(const MutexLock &) { return *this; }

public:
	__INLINE__ MutexLock(Mutex &mutex)
		: _mutex(mutex)
	{
		_mutex.lock();
	}

	__INLINE__ ~MutexLock(void)
	{
		_mutex.unlock();
	}
};


#define MUTEX_BEGIN(mutex)  { DECLARE_FUTILITY_VARIABLE(gdk::MutexLock, mutex); {
#define MUTEX_END()         } }



}//namespace gdk



#endif //__GDK_MUTEX_H__
